package com.atues.aspect;

import com.alibaba.fastjson.JSON;
import com.atues.annotation.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Component
@Aspect
@Slf4j
public class LogAspect {

    @Pointcut("@annotation(com.atues.annotation.SystemLog)")
    public void pt(){
 
    }

    @Around("pt()")
    public Object printLog(ProceedingJoinPoint joinPoint) {
        Object ret;
        try {
            handleBefore(joinPoint);
            ret = joinPoint.proceed();//执行目标方法
            handleAfter(joinPoint);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }finally {
            log.info("=========End=========",System.lineSeparator());
        }

        return  ret;


    }

    private void handleAfter(Object ret) {

//         打印出参
        log.info("Response : {}", JSON.toJSONString(ret ));
    }

    private void handleBefore(JoinPoint joinPoint) {
        ServletRequestAttributes requestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        SystemLog systemLog = getSystemLog(joinPoint);
        log.info("=======Start=======");
// 打印请求 URL
        log.info("URL : {}",request.getRequestURL());
// 打印描述信息
        log.info("BusinessName : {}", systemLog.businessName());
// 打印 Http method
        log.info("HTTP Method : {}", request.getMethod());
        Signature signature = joinPoint.getSignature();
// 打印调用 controller 的全路径以及执行方法
        log.info("Class Method : {}.{}",signature.getDeclaringTypeName(),((MethodSignature)signature).getName() );
// 打印请求的 IP
        log.info("IP : {}",request.getRemoteHost());
// 打印请求入参
        log.info("Request Args : {}",JSON.toJSONString(joinPoint.getArgs()));


    }

    private SystemLog getSystemLog(JoinPoint joinPoint) {

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SystemLog annotation = methodSignature.getMethod().getAnnotation(SystemLog.class);
        return annotation;
    }
}
